home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / pccp019.zip / XMODEMS.C < prev    next >
Text File  |  1992-05-04  |  6KB  |  343 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC: >qcl term.c graphics.lib
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<sys\types.h>
  10. #include<sys\stat.h>
  11. #include<signal.h>
  12.  
  13. #define DLLSBREG 0
  14. #define DLMSBREG 1
  15. #define INTCTLREG 1
  16. #define INTIDREG 2
  17. #define LCTLREG 3
  18. #define MCTLREG 4
  19. #define STATREG 5
  20. #define MSTATREG 6
  21.  
  22. #define CTSMASK 0x10
  23. #define TXMTMASK 0x20
  24. #define RXRDYMASK 0x01
  25.  
  26. #define INTACK 0x20
  27.  
  28. #define DB7 0x02
  29. #define DB8 0x03
  30. #define STOP2 0x04
  31. #define PARITYEN 0x08
  32. #define PARITYEVEN 0x10
  33. #define DLAB 0x80
  34.  
  35. #define INTBASE1 0x20
  36. #define INTMASK1 0x21
  37. #define INTBASE2 0xa0
  38. #define INTMASK2 0xa1
  39.  
  40. #define TBUFSIZ 256
  41.  
  42. #define NAK 21
  43. #define ACK 6
  44. #define SOH 1
  45. #define EOT 4
  46. #define CAN 24
  47.  
  48. int index, basereg;
  49. unsigned char buf[TBUFSIZ];
  50. unsigned char diffintmask, irqnum;
  51. void (interrupt far *oldvect)();
  52.  
  53. void interrupt far inthndl(_es, _ds, _di, _si, _bp, _sp,
  54.               _bx, _dx, _cx, _ax, _ip, _cs, _flags)
  55.     unsigned _es, _ds, _di, _si, _bp, _sp;
  56.     unsigned _bx, _dx, _cx, _ax, _ip, _cs, _flags;
  57.     {
  58.     if(inp(basereg+STATREG)&RXRDYMASK)
  59.         {
  60.         buf[index++]=inp(basereg)&0xff;
  61.         index=index%TBUFSIZ;
  62.         }
  63.     outp(INTBASE1, INTACK);
  64.     outp(INTBASE2, INTACK);
  65.     }
  66.  
  67. sendchar(c)
  68.     unsigned char c;
  69.     {
  70.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)));
  71.     outp(basereg, c);
  72.     }
  73.  
  74. int follow;
  75.  
  76. int rcharto(ticks)
  77.     int ticks;
  78.     {
  79.     long tstamp, tstamp1, dayofticksp;
  80.     int c;
  81.     _bios_timeofday(_TIME_GETCLOCK, &tstamp);
  82.     dayofticksp=0;
  83.     while(1)
  84.         {
  85.         if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
  86.             dayofticksp+=20*60*60*24;
  87.         if(tstamp1+dayofticksp-tstamp>ticks)
  88.             return(-1); /* NOTE: This is an INT!!! */
  89.         if(follow!=index)
  90.             {
  91.             c=buf[follow++];
  92.             follow=follow%TBUFSIZ;
  93.             return(c);
  94.             }
  95.         }
  96.     }
  97.  
  98.  
  99. unsigned char block[128];
  100.  
  101. sblock(blockn)
  102.     unsigned char blockn;
  103.     {
  104.     int i;
  105.     unsigned char checksum;
  106.     checksum=0;
  107.     sendchar(SOH);
  108.     sendchar(blockn);
  109.     sendchar((blockn^0xff)&0xff);
  110.     for(i=0;i<128;++i)
  111.         {
  112.         sendchar(block[i]);
  113.         checksum+=block[i];
  114.         }
  115.     sendchar(checksum);
  116.     }
  117.  
  118. unsigned intnum;
  119. unsigned char oldintmask;
  120.  
  121. cleanup()
  122.     {
  123.     if(intnum==10)
  124.         outp(INTMASK2, oldintmask);
  125.     else
  126.         outp(INTMASK1, oldintmask);
  127.     outp(basereg+INTCTLREG, 0x00);
  128.     outp(basereg+MCTLREG, 0x03);
  129.     _dos_setvect(intnum, oldvect);
  130.     }
  131.  
  132. quit()
  133.     {
  134.     cleanup();
  135.     exit(99);
  136.     }
  137.  
  138. main(argc, argv)
  139.     int argc;
  140.     char **argv;
  141.     {
  142.     int i, j, infd, ok, c;
  143.     unsigned char newintmask, lctl, dlmsb, dllsb, blocknum;
  144.     long nbytes;
  145.     unsigned speed;
  146.     int comnum;
  147.     char stopbits;
  148.     index=follow=0;
  149.     lctl=0;
  150.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  151.     printf("xmodem checksum send of %s.\n", argv[4]);
  152.     if(argc!=5)
  153.         {
  154.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  155.         exit(1);
  156.         }
  157.     if((infd=open(argv[4], O_RDONLY|O_BINARY))==-1)
  158.         {
  159.         printf("Error opening file %s.\n", argv[4]);
  160.         exit(2);
  161.         }
  162.     comnum=atoi(argv[1])-1;
  163.     newintmask=0;
  164.     switch(comnum)
  165.         {
  166.         case 0:
  167.             irqnum=4;
  168.             diffintmask=0xff&~0x10;
  169.             basereg=0x3f8;
  170.             break;
  171.         case 1:
  172.             irqnum=3;
  173.             diffintmask=0xff&~0x08;
  174.             basereg=0x2f8;
  175.             break;
  176.         case 2:
  177.             irqnum=4;
  178.             diffintmask=0xff&~0x10;
  179.             basereg=0x3e8;
  180.             break;
  181.         case 3:
  182.             irqnum=3;
  183.             diffintmask=0xff&~0x08;
  184.             basereg=0x2e8;
  185.             break;
  186.         case 4:
  187.             irqnum=2;
  188.             diffintmask=0xff&~0x02;
  189.             basereg=0x3e8;
  190.             break;
  191.         case 5:
  192.             irqnum=2;
  193.             diffintmask=0xff&~0x02;
  194.             basereg=0x2e8;
  195.             break;
  196.         case 6:
  197.             irqnum=5;
  198.             diffintmask=0xff&~0x20;
  199.             basereg=0x3e8;
  200.             break;
  201.         case 7:
  202.             irqnum=5;
  203.             diffintmask=0xff&~0x20;
  204.             basereg=0x2e8;
  205.             break;
  206.         default:
  207.             printf("Bad port choice.\n");
  208.             exit(4);
  209.         }
  210.     intnum=irqnum+8;
  211.     speed=atoi(argv[2]);
  212.     switch(speed)
  213.         {
  214.         case 300:
  215.             dlmsb=0;
  216.             dllsb=0xc0;
  217.             break;
  218.         case 1200:
  219.             dlmsb=0;
  220.             dllsb=0x60;
  221.             break;
  222.         case 2400:
  223.             dlmsb=0;
  224.             dllsb=0x30;
  225.             break;
  226.         case 9600:
  227.             dlmsb=0;
  228.             dllsb=0x0c;
  229.             break;
  230.         case 19200:
  231.             dlmsb=0;
  232.             dllsb=0x06;
  233.             break;
  234.         case 38400:
  235.             dlmsb=0;
  236.             dllsb=0x03;
  237.             break;
  238.         case 57600:
  239.             dlmsb=0;
  240.             dllsb=0x02;
  241.             break;
  242.         default:
  243.             printf("Bad speed.\n");
  244.             exit(5);
  245.         }
  246.     lctl|=DB8;
  247.     stopbits=argv[3][0];
  248.     switch(stopbits)
  249.         {
  250.         case '1':
  251.             break;
  252.         case '2':
  253.             lctl|=STOP2;
  254.             break;
  255.         default:
  256.             printf("Bad stop bits.\n");
  257.             exit(9);
  258.         }
  259.     signal(SIGINT, quit);
  260.     outp(basereg+LCTLREG, DLAB);
  261.     outp(basereg+DLLSBREG, dllsb);
  262.     outp(basereg+DLMSBREG, dlmsb);
  263.     outp(basereg+LCTLREG, lctl);
  264.     oldvect=_dos_getvect(intnum);
  265.     _dos_setvect(intnum, inthndl);
  266.     outp(basereg+INTCTLREG, 0x00);
  267.     outp(basereg+MCTLREG, 0x0b);
  268.     oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1);
  269.     newintmask=diffintmask;
  270.     newintmask&=oldintmask;
  271.     if(intnum==10)
  272.         outp(INTMASK2, newintmask);
  273.     else
  274.         outp(INTMASK1, newintmask);
  275.     outp(INTBASE1, INTACK);
  276.     outp(INTBASE2, INTACK);
  277.     outp(basereg+INTCTLREG, 0x01);
  278.     outp(INTBASE1, INTACK);
  279.     outp(INTBASE2, INTACK);
  280.     nbytes=0;
  281.     if(rcharto(2000)!=NAK)
  282.         {
  283.         printf("Spurrious char or no NAK in 100 seconds.\n");
  284.         cleanup();
  285.         exit(10);
  286.         }
  287.     blocknum=1;
  288.     while(1)
  289.         {
  290.         if((j=read(infd, block, 128))==0)
  291.             {
  292.             printf("End of file.\n");
  293.             sendchar(EOT);
  294.             do
  295.                 c=rcharto(300);
  296.             while((c!=ACK)&&(c!=NAK)&&(c!=-1));
  297.             if(c!=ACK)
  298.                 {
  299.                 printf("\nNo ACK of EOT.\n");
  300.                 cleanup();
  301.                 exit(13);
  302.                 }
  303.             else
  304.                 {
  305.                 printf("\nSuccessful.\n");
  306.                 cleanup();
  307.                 exit(0);    
  308.                 }
  309.             }
  310.         for(c=j;c<128;c++)
  311.             block[c]=26;
  312.         i=0;
  313.         do
  314.             {
  315.             printf("\nSending block %d. ", blocknum);
  316.             sblock(blocknum);
  317.             do
  318.                 c=rcharto(200);
  319.             while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  320.             }
  321.         while((c==NAK)&&(i++<10));
  322.         if(c!=ACK)
  323.             if(c==NAK)
  324.                 {
  325.                 printf("\nRetry limit exceeded.\n");
  326.                 cleanup();
  327.                 exit(14);
  328.                 }
  329.             else
  330.                 {
  331.                 printf("\nSpurrious character hex %02x; ACK or NAK expected.\n", c);
  332.                 cleanup();
  333.                 exit(11);
  334.                 }
  335.         nbytes+=128;
  336.         printf("Successful. Bytes so far: %ld", nbytes);
  337.         blocknum++;
  338.         }
  339.     printf("Programming error; fell through end; see code.\n");
  340.     cleanup();
  341.     exit(12);
  342.     }
  343.